package enums

import (
	"gitee.com/hongzhaomin/gspring/annotation"
	"gitee.com/hongzhaomin/gspring/tools"
	"reflect"
)

var (
	rtInitialize = reflect.TypeOf((*annotation.Initialize)(nil)).Elem()
)

type Annotation uint

func (my Annotation) String() string {
	switch my {
	case InvalidAnno:
		return rtInitialize.Name()
	default:
		return ""
	}
}

func (my Annotation) Is(anno Annotation) bool {
	return my == anno
}

func (my Annotation) IsValid() bool {
	return !InvalidAnno.Is(my)
}

func GetAnnoTagValue(refType reflect.Type, anno Annotation, tagName string) (string, bool) {
	return tools.FindAnnotationValueByType(refType, anno.GetAnnotationType(), tagName)
}

func (my Annotation) GetAnnotationType() any {
	switch my {
	case Initialize:
		return (*annotation.Initialize)(nil)
	default:
		return nil
	}
}

const (
	InvalidAnno Annotation = iota
	Initialize
)

var annoMap = map[Annotation]reflect.Type{
	InvalidAnno: nil,
	Initialize:  rtInitialize,
}

func GetAnnotationEnum(bean any) Annotation {
	// 为了不引用annotation包中的注解接口，使用反射的方式进行判断
	return GetAnnotationEnumByType(tools.IndirectReflectType(bean))
}

func GetAnnotationEnumByType(refType reflect.Type) Annotation {
	switch {
	case refType.Implements(rtInitialize) ||
		reflect.New(refType).Type().Implements(rtInitialize):
		return Initialize
	default:
		return InvalidAnno
	}
}

func AnnotationIs(refType reflect.Type, anno Annotation) bool {
	rt := annoMap[anno]
	return refType.Implements(rt) || reflect.New(refType).Type().Implements(rt)
}
